package com.xinsoft.common;

import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.HashMap;
import java.util.Map;

/**
 * 文件安全判断
 */
public class GetFileTypeByHeadUtil {

    // 缓存文件头信息-文件头信息
    public static final HashMap<String, String> mFileTypes = new HashMap<String, String>();

    static {
        // images
        mFileTypes.put("4D5A", "exe");
        mFileTypes.put("4065", "bat");
        mFileTypes.put("2321", "sh");
    }

    /**
     * 根据文件流判断是否为可执行文件
     * @param is
     * @return
     */
    public static String getFileTypeByInputStream(InputStream is){
        String value = "";
        try {
            byte[] b = new byte[20];
            is.read(b, 0, b.length);
            value = bytesToHexString(b);
        } catch (Exception e) {
        } finally {
            if (null != is) {
                try {
                    is.close();
                } catch (IOException e) {
                }
            }
        }
        String result = "";
        for (Map.Entry<String, String> entry : mFileTypes.entrySet()) {
            if (value.startsWith(entry.getKey())) {
                result = entry.getValue();
            }
        }
        return result;
    }

    /**
     * 根据文件路径获取文件类型
     *
     * @param filePath
     *            文件路径
     * @return 文件类型
     */
    public static String getFileType(String filePath) {
        String value = getFileHeader(filePath);
        String result = "";
        for (Map.Entry<String, String> entry : mFileTypes.entrySet()) {
            if (value.startsWith(entry.getKey())) {
                result = entry.getValue();
            }
        }
        return result;
    }

    /**
     * 根据文件路径获取文件头信息
     *
     * @param filePath
     *            文件路径
     * @return 文件头信息
     */
    public static String getFileHeader(String filePath) {
        FileInputStream is = null;
        String value = "";
        try {
            is = new FileInputStream(filePath);
            byte[] b = new byte[20];
            is.read(b, 0, b.length);
            value = bytesToHexString(b);
        } catch (Exception e) {
        } finally {
            if (null != is) {
                try {
                    is.close();
                } catch (IOException e) {
                }
            }
        }
        return value;
    }

    /**
     * 将要读取文件头信息的文件的byte数组转换成string类型表示
     *
     * @param src
     *            要读取文件头信息的文件的byte数组
     * @return 文件头十六进制信息
     */
    private static String bytesToHexString(byte[] src) {
        StringBuilder builder = new StringBuilder();
        if (src == null || src.length <= 0) {
            return null;
        }
        String hv;
        for (int i = 0; i < src.length; i++) {
            // 以十六进制（基数 16）无符号整数形式返回一个整数参数的字符串表示形式，并转换为大写
            hv = Integer.toHexString(src[i] & 0xFF).toUpperCase();
            if (hv.length() < 2) {
                builder.append(0);
            }
            builder.append(hv);
        }
        System.out.println("HexString: " + builder.toString());
        return builder.toString();
    }
}
